🎖️GitЯра🎖️
src/helpers/BaseChatMesh.cpp 890a2e2cffa98dea3ca88db3c3aba72ef23ff3f7 (890a2e2c) Text, 36.84 KB
Tff7b72#Tff7b72include T8b949e<helpers/BaseChatMesh.h>
Tff7b72#Tff7b72include T8b949e<Utils.h>
Tff7b72#Tff7b72ifndef SERVER_RESPONSE_DELAY
Tff7b72#Tff7b72define SERVER_RESPONSE_DELAY 300
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef TXT_ACK_DELAY
Tff7b72#Tff7b72define TXT_ACK_DELAY 200
Tff7b72#Tff7b72endif
Tffa657void Td2a8ffBaseChatMesh::sendFloodScopedTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3recipientTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3pktTb4b4b4, Tffa657uint32_t Te6edf3delay_millisTb4b4b4) Tb4b4b4{
Te6edf3sendFloodTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3delay_millisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::sendFloodScopedTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3GroupChannelTff7b72& Te6edf3channelTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3pktTb4b4b4, Tffa657uint32_t Te6edf3delay_millisTb4b4b4) Tb4b4b4{
Te6edf3sendFloodTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3delay_millisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Td2a8ffBaseChatMesh::createSelfAdvertTb4b4b4(Tff7b72const Tffa657charTff7b72* Te6edf3nameTb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3app_dataTb4b4b4[Te6edf3MAX_ADVERT_DATA_SIZETb4b4b4]Tb4b4b4;
Tffa657uint8_t Te6edf3app_data_lenTb4b4b4;
Tb4b4b4{
Te6edf3AdvertDataBuilder Te6edf3builderTb4b4b4(Te6edf3ADV_TYPE_CHATTb4b4b4, Te6edf3nameTb4b4b4)Tb4b4b4;
Te6edf3app_data_len Tff7b72= Te6edf3builderTb4b4b4.Te6edf3encodeToTb4b4b4(Te6edf3app_dataTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3createAdvertTb4b4b4(Te6edf3self_idTb4b4b4, Te6edf3app_dataTb4b4b4, Te6edf3app_data_lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Td2a8ffBaseChatMesh::createSelfAdvertTb4b4b4(Tff7b72const Tffa657charTff7b72* Te6edf3nameTb4b4b4, Tffa657double Te6edf3latTb4b4b4, Tffa657double Te6edf3lonTb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3app_dataTb4b4b4[Te6edf3MAX_ADVERT_DATA_SIZETb4b4b4]Tb4b4b4;
Tffa657uint8_t Te6edf3app_data_lenTb4b4b4;
Tb4b4b4{
Te6edf3AdvertDataBuilder Te6edf3builderTb4b4b4(Te6edf3ADV_TYPE_CHATTb4b4b4, Te6edf3nameTb4b4b4, Te6edf3latTb4b4b4, Te6edf3lonTb4b4b4)Tb4b4b4;
Te6edf3app_data_len Tff7b72= Te6edf3builderTb4b4b4.Te6edf3encodeToTb4b4b4(Te6edf3app_dataTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3createAdvertTb4b4b4(Te6edf3self_idTb4b4b4, Te6edf3app_dataTb4b4b4, Te6edf3app_data_lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::sendAckToTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3destTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3ack_hashTb4b4b4, Tffa657uint8_t Te6edf3ack_lenTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3destTb4b4b4.Te6edf3out_path_len Tff7b72=Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3ack Tff7b72= Te6edf3createAckTb4b4b4(Te6edf3ack_hashTb4b4b4, Te6edf3ack_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3ackTb4b4b4) Te6edf3sendFloodScopedTb4b4b4(Te6edf3destTb4b4b4, Te6edf3ackTb4b4b4, Te6edf3TXT_ACK_DELAYTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tffa657uint32_t Te6edf3d Tff7b72= Te6edf3TXT_ACK_DELAYTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3getExtraAckTransmitCountTb4b4b4(Tb4b4b4) Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3a1 Tff7b72= Te6edf3createMultiAckTb4b4b4(Te6edf3ack_hashTb4b4b4, Te6edf3ack_lenTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3a1Tb4b4b4) Te6edf3sendDirectTb4b4b4(Te6edf3a1Tb4b4b4, Te6edf3destTb4b4b4.Te6edf3out_pathTb4b4b4, Te6edf3destTb4b4b4.Te6edf3out_path_lenTb4b4b4, Te6edf3dTb4b4b4)Tb4b4b4;
Te6edf3d Tff7b72+Tff7b72= T79c0ff300Tb4b4b4;
Tb4b4b4}
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3a2 Tff7b72= Te6edf3createAckTb4b4b4(Te6edf3ack_hashTb4b4b4, Te6edf3ack_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3a2Tb4b4b4) Te6edf3sendDirectTb4b4b4(Te6edf3a2Tb4b4b4, Te6edf3destTb4b4b4.Te6edf3out_pathTb4b4b4, Te6edf3destTb4b4b4.Te6edf3out_path_lenTb4b4b4, Te6edf3dTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::bootstrapRTCfromContactsTb4b4b4(Tb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3latest Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3num_contactsTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3lastmod Tff7b72> Te6edf3latestTb4b4b4) Tb4b4b4{
Te6edf3latest Tff7b72= Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3lastmodTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3latest Tff7b72!Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3setCurrentTimeTb4b4b4(Te6edf3latest Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3ContactInfoTff7b72* Td2a8ffBaseChatMesh::allocateContactSlotTb4b4b4(Tffa657bool Te6edf3transient_onlyTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3oldest_idx Tff7b72= T79c0ff-1Tb4b4b4;
Tffa657uint32_t Te6edf3oldest_lastmod Tff7b72= T79c0ff0xFFFFFFFFTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3transient_onlyTb4b4b4) Tb4b4b4{
T8b949e// only allocate from first N
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_ANON_CONTACTSTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3type Tff7b72=Tff7b72= Te6edf3ADV_TYPE_NONE Tff7b72&Tff7b72& Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3lastmod Tff7b72< Te6edf3oldest_lastmodTb4b4b4) Tb4b4b4{
Te6edf3oldest_lastmod Tff7b72= Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3lastmodTb4b4b4;
Te6edf3oldest_idx Tff7b72= Te6edf3iTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3oldest_idx Tff7b72>Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// NOTE: do NOT call onContactOverwrite()
Tff7b72return Tff7b72&Te6edf3contactsTb4b4b4[Te6edf3oldest_idxTb4b4b4]Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3num_contacts Tff7b72< Te6edf3MAX_ANON_CONTACTSTff7b72+Te6edf3MAX_CONTACTSTb4b4b4) Tb4b4b4{
Tff7b72return Tff7b72&Te6edf3contactsTb4b4b4[Te6edf3num_contactsTff7b72+Tff7b72+Tb4b4b4]Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3shouldOverwriteWhenFullTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// Find oldest non-favourite contact by oldest lastmod timestamp
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= Te6edf3MAX_ANON_CONTACTSTb4b4b4; Te6edf3i Tff7b72< Te6edf3num_contactsTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3is_favourite Tff7b72= Tb4b4b4(Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3flags Tff7b72& T79c0ff0x01Tb4b4b4) Tff7b72!Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3is_favourite Tff7b72&Tff7b72& Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3lastmod Tff7b72< Te6edf3oldest_lastmodTb4b4b4) Tb4b4b4{
Te6edf3oldest_lastmod Tff7b72= Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3lastmodTb4b4b4;
Te6edf3oldest_idx Tff7b72= Te6edf3iTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3oldest_idx Tff7b72>Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3onContactOverwriteTb4b4b4(Te6edf3contactsTb4b4b4[Te6edf3oldest_idxTb4b4b4]Tb4b4b4.Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4)Tb4b4b4;
Tff7b72return Tff7b72&Te6edf3contactsTb4b4b4[Te6edf3oldest_idxTb4b4b4]Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72return Tffa657NULLTb4b4b4; T8b949e// no space, no overwrite or all contacts are all favourites
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::populateContactFromAdvertTb4b4b4(Te6edf3ContactInfoTff7b72& Te6edf3ciTb4b4b4, Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3IdentityTff7b72& Te6edf3idTb4b4b4, Tff7b72const Te6edf3AdvertDataParserTff7b72& Te6edf3parserTb4b4b4, Tffa657uint32_t Te6edf3timestampTb4b4b4) Tb4b4b4{
Te6edf3memsetTb4b4b4(Tff7b72&Te6edf3ciTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3ciTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3ciTb4b4b4.Te6edf3id Tff7b72= Te6edf3idTb4b4b4;
Te6edf3ciTb4b4b4.Te6edf3out_path_len Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4;
Te6edf3StrHelperTff7b72:Tff7b72:Te6edf3strncpyTb4b4b4(Te6edf3ciTb4b4b4.Te6edf3nameTb4b4b4, Te6edf3parserTb4b4b4.Te6edf3getNameTb4b4b4(Tb4b4b4)Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3ciTb4b4b4.Te6edf3nameTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3ciTb4b4b4.Te6edf3type Tff7b72= Te6edf3parserTb4b4b4.Te6edf3getTypeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3parserTb4b4b4.Te6edf3hasLatLonTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3ciTb4b4b4.Te6edf3gps_lat Tff7b72= Te6edf3parserTb4b4b4.Te6edf3getIntLatTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3ciTb4b4b4.Te6edf3gps_lon Tff7b72= Te6edf3parserTb4b4b4.Te6edf3getIntLonTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3ciTb4b4b4.Te6edf3last_advert_timestamp Tff7b72= Te6edf3timestampTb4b4b4;
Te6edf3ciTb4b4b4.Te6edf3lastmod Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::onAdvertRecvTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3packetTb4b4b4, Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3IdentityTff7b72& Te6edf3idTb4b4b4, Tffa657uint32_t Te6edf3timestampTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3app_dataTb4b4b4, Tffa657size_t Te6edf3app_data_lenTb4b4b4) Tb4b4b4{
Te6edf3AdvertDataParser Te6edf3parserTb4b4b4(Te6edf3app_dataTb4b4b4, Te6edf3app_data_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Tb4b4b4(Te6edf3parserTb4b4b4.Te6edf3isValidTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3parserTb4b4b4.Te6edf3hasNameTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonAdvertRecv: invalid app_data, or name is missing: len=%dTa5d6ff"Tb4b4b4, Te6edf3app_data_lenTb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3ContactInfoTff7b72* Te6edf3from Tff7b72= Tffa657NULLTb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3num_contactsTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3idTb4b4b4.Te6edf3matchesTb4b4b4(Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3idTb4b4b4)Tb4b4b4) Tb4b4b4{ T8b949e// is from one of our contacts
Te6edf3from Tff7b72= Tff7b72&Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3timestamp Tff7b72<Tff7b72= Te6edf3fromTff7b72-Tff7b72>Te6edf3last_advert_timestampTb4b4b4) Tb4b4b4{ T8b949e// check for replay attacks!!
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonAdvertRecv: Possible replay attack, name: %sTa5d6ff"Tb4b4b4, Te6edf3fromTff7b72-Tff7b72>Te6edf3nameTb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// save a copy of raw advert packet (to support "Share..." function)
Tffa657int Te6edf3plenTb4b4b4;
Tb4b4b4{
Tffa657uint8_t Te6edf3save Tff7b72= Te6edf3packetTff7b72-Tff7b72>Te6edf3headerTb4b4b4;
Te6edf3packetTff7b72-Tff7b72>Te6edf3header Tff7b72&Tff7b72= Tff7b72~Te6edf3PH_ROUTE_MASKTb4b4b4;
Te6edf3packetTff7b72-Tff7b72>Te6edf3header Tff7b72|Tff7b72= Te6edf3ROUTE_TYPE_FLOODTb4b4b4; T8b949e// make sure transport codes are NOT saved
Te6edf3plen Tff7b72= Te6edf3packetTff7b72-Tff7b72>Te6edf3writeToTb4b4b4(Te6edf3temp_bufTb4b4b4)Tb4b4b4;
Te6edf3packetTff7b72-Tff7b72>Te6edf3header Tff7b72= Te6edf3saveTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3from Tff7b72&Tff7b72& Te6edf3fromTff7b72-Tff7b72>Te6edf3type Tff7b72=Tff7b72= Te6edf3ADV_TYPE_NONETb4b4b4) Tb4b4b4{ T8b949e// already in contacts, but from a temporary ANON_REQ ?
Te6edf3memsetTb4b4b4(Te6edf3fromTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Tff7b72*Te6edf3fromTb4b4b4)Tb4b4b4)Tb4b4b4; T8b949e// clear the anon/temp slot
Te6edf3from Tff7b72= Tffa657NULLTb4b4b4; T8b949e// do normal 'add' flow
Tb4b4b4}
Tffa657bool Te6edf3is_new Tff7b72= Tffa657falseTb4b4b4; T8b949e// true = not in contacts[], false = exists in contacts[]
Tff7b72if Tb4b4b4(Te6edf3from Tff7b72=Tff7b72= Tffa657NULLTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3shouldAutoAddContactTypeTb4b4b4(Te6edf3parserTb4b4b4.Te6edf3getTypeTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3ContactInfo Te6edf3ciTb4b4b4;
Te6edf3populateContactFromAdvertTb4b4b4(Te6edf3ciTb4b4b4, Te6edf3idTb4b4b4, Te6edf3parserTb4b4b4, Te6edf3timestampTb4b4b4)Tb4b4b4;
Te6edf3onDiscoveredContactTb4b4b4(Te6edf3ciTb4b4b4, Tffa657trueTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4)Tb4b4b4; T8b949e// let UI know
Tff7b72returnTb4b4b4;
Tb4b4b4}
T8b949e// check hop limit for new contacts (0 = no limit, 1 = direct (0 hops), N = up to N-1 hops)
Tffa657uint8_t Te6edf3max_hops Tff7b72= Te6edf3getAutoAddMaxHopsTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3max_hops Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3packetTff7b72-Tff7b72>Te6edf3getPathHashCountTb4b4b4(Tb4b4b4) Tff7b72>Tff7b72= Te6edf3max_hopsTb4b4b4) Tb4b4b4{
Te6edf3ContactInfo Te6edf3ciTb4b4b4;
Te6edf3populateContactFromAdvertTb4b4b4(Te6edf3ciTb4b4b4, Te6edf3idTb4b4b4, Te6edf3parserTb4b4b4, Te6edf3timestampTb4b4b4)Tb4b4b4;
Te6edf3onDiscoveredContactTb4b4b4(Te6edf3ciTb4b4b4, Tffa657trueTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4)Tb4b4b4; T8b949e// let UI know
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3from Tff7b72= Te6edf3allocateContactSlotTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3from Tff7b72=Tff7b72= Tffa657NULLTb4b4b4) Tb4b4b4{
Te6edf3ContactInfo Te6edf3ciTb4b4b4;
Te6edf3populateContactFromAdvertTb4b4b4(Te6edf3ciTb4b4b4, Te6edf3idTb4b4b4, Te6edf3parserTb4b4b4, Te6edf3timestampTb4b4b4)Tb4b4b4;
Te6edf3onDiscoveredContactTb4b4b4(Te6edf3ciTb4b4b4, Tffa657trueTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4)Tb4b4b4;
Te6edf3onContactsFullTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonAdvertRecv: unable to allocate contact slot for new contactTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3populateContactFromAdvertTb4b4b4(Tff7b72*Te6edf3fromTb4b4b4, Te6edf3idTb4b4b4, Te6edf3parserTb4b4b4, Te6edf3timestampTb4b4b4)Tb4b4b4;
Te6edf3fromTff7b72-Tff7b72>Te6edf3sync_since Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3fromTff7b72-Tff7b72>Te6edf3shared_secret_valid Tff7b72= Tffa657falseTb4b4b4;
Tb4b4b4}
T8b949e// update
Te6edf3putBlobByKeyTb4b4b4(Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4, Te6edf3temp_bufTb4b4b4, Te6edf3plenTb4b4b4)Tb4b4b4;
Te6edf3StrHelperTff7b72:Tff7b72:Te6edf3strncpyTb4b4b4(Te6edf3fromTff7b72-Tff7b72>Te6edf3nameTb4b4b4, Te6edf3parserTb4b4b4.Te6edf3getNameTb4b4b4(Tb4b4b4)Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3fromTff7b72-Tff7b72>Te6edf3nameTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3fromTff7b72-Tff7b72>Te6edf3type Tff7b72= Te6edf3parserTb4b4b4.Te6edf3getTypeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3parserTb4b4b4.Te6edf3hasLatLonTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3fromTff7b72-Tff7b72>Te6edf3gps_lat Tff7b72= Te6edf3parserTb4b4b4.Te6edf3getIntLatTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3fromTff7b72-Tff7b72>Te6edf3gps_lon Tff7b72= Te6edf3parserTb4b4b4.Te6edf3getIntLonTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3fromTff7b72-Tff7b72>Te6edf3last_advert_timestamp Tff7b72= Te6edf3timestampTb4b4b4;
Te6edf3fromTff7b72-Tff7b72>Te6edf3lastmod Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3onDiscoveredContactTb4b4b4(Tff7b72*Te6edf3fromTb4b4b4, Te6edf3is_newTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4)Tb4b4b4; T8b949e// let UI know
Tb4b4b4}
Tffa657int Td2a8ffBaseChatMesh::searchPeersByHashTb4b4b4(Tff7b72const Tffa657uint8_tTff7b72* Te6edf3hashTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3n Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3num_contacts Tff7b72&Tff7b72& Te6edf3n Tff7b72< Te6edf3MAX_SEARCH_RESULTSTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3idTb4b4b4.Te6edf3isHashMatchTb4b4b4(Te6edf3hashTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3matching_peer_indexesTb4b4b4[Te6edf3nTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3iTb4b4b4; T8b949e// store the INDEXES of matching contacts (for subsequent 'peer' methods)
Tb4b4b4}
Tb4b4b4}
Tff7b72return Te6edf3nTb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::getPeerSharedSecretTb4b4b4(Tffa657uint8_tTff7b72* Te6edf3dest_secretTb4b4b4, Tffa657int Te6edf3peer_idxTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3i Tff7b72= Te6edf3matching_peer_indexesTb4b4b4[Te6edf3peer_idxTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3i Tff7b72>Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3i Tff7b72< Te6edf3num_contactsTb4b4b4) Tb4b4b4{
Te6edf3memcpyTb4b4b4(Te6edf3dest_secretTb4b4b4, Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3getSharedSecretTb4b4b4(Te6edf3self_idTb4b4b4)Tb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffgetPeerSharedSecret: Invalid peer idx: %dTa5d6ff"Tb4b4b4, Te6edf3iTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::onPeerDataRecvTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3packetTb4b4b4, Tffa657uint8_t Te6edf3typeTb4b4b4, Tffa657int Te6edf3sender_idxTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3secretTb4b4b4, Tffa657uint8_tTff7b72* Te6edf3dataTb4b4b4, Tffa657size_t Te6edf3lenTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3i Tff7b72= Te6edf3matching_peer_indexesTb4b4b4[Te6edf3sender_idxTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3i Tff7b72< T79c0ff0 Tff7b72|Tff7b72| Te6edf3i Tff7b72>Tff7b72= Te6edf3num_contactsTb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonPeerDataRecv: Invalid sender idx: %dTa5d6ff"Tb4b4b4, Te6edf3iTb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3ContactInfoTff7b72& Te6edf3from Tff7b72= Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_TXT_MSG Tff7b72&Tff7b72& Te6edf3len Tff7b72> T79c0ff5Tb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3timestampTb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3timestampTb4b4b4, Te6edf3dataTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// timestamp (by sender's RTC clock - which could be wrong)
Tffa657uint8_t Te6edf3flags Tff7b72= Te6edf3dataTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72>Tff7b72> T79c0ff2Tb4b4b4; T8b949e// message attempt number, and other flags
T8b949e// len can be > original length, but 'text' will be padded with zeroes
Te6edf3dataTb4b4b4[Te6edf3lenTb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// need to make a C string again, with null terminator
Tff7b72if Tb4b4b4(Te6edf3flags Tff7b72=Tff7b72= Te6edf3TXT_TYPE_PLAINTb4b4b4) Tb4b4b4{
Te6edf3fromTb4b4b4.Te6edf3lastmod Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4; T8b949e// update last heard time
Te6edf3onMessageRecvTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3packetTb4b4b4, Te6edf3timestampTb4b4b4, Tb4b4b4(Tff7b72const Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3dataTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4)Tb4b4b4; T8b949e// let UI know
Tffa657int Te6edf3text_len Tff7b72= Te6edf3strlenTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4)Tff7b72&Te6edf3dataTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tffa657uint8_t Te6edf3ack_hashTb4b4b4[T79c0ff6Tb4b4b4]Tb4b4b4; T8b949e// calc truncated hash of the message timestamp + text + sender pub_key, to prove to sender that we got it
Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3sha256Tb4b4b4(Te6edf3ack_hashTb4b4b4, T79c0ff4Tb4b4b4, Te6edf3dataTb4b4b4, T79c0ff5 Tff7b72+ Te6edf3text_lenTb4b4b4, Te6edf3fromTb4b4b4.Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
T8b949e// NEW: append (potential) extended attempt byte (to make packethash unique)
Te6edf3ack_hashTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72= Te6edf3dataTb4b4b4[T79c0ff5 Tff7b72+ Te6edf3text_len Tff7b72+ T79c0ff1Tb4b4b4]Tb4b4b4;
Te6edf3getRNGTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3randomTb4b4b4(Tff7b72&Te6edf3ack_hashTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4; T8b949e// make 6th byte random
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteFloodTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the ACK
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3path Tff7b72= Te6edf3createPathReturnTb4b4b4(Te6edf3fromTb4b4b4.Te6edf3idTb4b4b4, Te6edf3secretTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4,
Te6edf3PAYLOAD_TYPE_ACKTb4b4b4, Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4) Tff7b72&Te6edf3ack_hashTb4b4b4, T79c0ff6Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pathTb4b4b4) Te6edf3sendFloodScopedTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3TXT_ACK_DELAYTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendAckToTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3ack_hashTb4b4b4, T79c0ff6Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3flags Tff7b72=Tff7b72= Te6edf3TXT_TYPE_CLI_DATATb4b4b4) Tb4b4b4{
Te6edf3onCommandDataRecvTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3packetTb4b4b4, Te6edf3timestampTb4b4b4, Tb4b4b4(Tff7b72const Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3dataTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4)Tb4b4b4; T8b949e// let UI know
T8b949e// NOTE: no ack expected for CLI_DATA replies
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteFloodTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// let this sender know path TO here, so they can use sendDirect() (NOTE: no ACK as extra)
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3path Tff7b72= Te6edf3createPathReturnTb4b4b4(Te6edf3fromTb4b4b4.Te6edf3idTb4b4b4, Te6edf3secretTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4, T79c0ff0Tb4b4b4, Tffa657NULLTb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pathTb4b4b4) Te6edf3sendFloodScopedTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3pathTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3flags Tff7b72=Tff7b72= Te6edf3TXT_TYPE_SIGNED_PLAINTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3timestamp Tff7b72> Te6edf3fromTb4b4b4.Te6edf3sync_sinceTb4b4b4) Tb4b4b4{ T8b949e// make sure 'sync_since' is up-to-date
Te6edf3fromTb4b4b4.Te6edf3sync_since Tff7b72= Te6edf3timestampTb4b4b4;
Tb4b4b4}
Te6edf3fromTb4b4b4.Te6edf3lastmod Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4; T8b949e// update last heard time
Te6edf3onSignedMessageRecvTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3packetTb4b4b4, Te6edf3timestampTb4b4b4, Tff7b72&Te6edf3dataTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4, Tb4b4b4(Tff7b72const Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3dataTb4b4b4[T79c0ff9Tb4b4b4]Tb4b4b4)Tb4b4b4; T8b949e// let UI know
Tffa657uint32_t Te6edf3ack_hashTb4b4b4; T8b949e// calc truncated hash of the message timestamp + text + OUR pub_key, to prove to sender that we got it
Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3sha256Tb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4) Tff7b72&Te6edf3ack_hashTb4b4b4, T79c0ff4Tb4b4b4, Te6edf3dataTb4b4b4, T79c0ff9 Tff7b72+ Te6edf3strlenTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4)Tff7b72&Te6edf3dataTb4b4b4[T79c0ff9Tb4b4b4]Tb4b4b4)Tb4b4b4, Te6edf3self_idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteFloodTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the ACK
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3path Tff7b72= Te6edf3createPathReturnTb4b4b4(Te6edf3fromTb4b4b4.Te6edf3idTb4b4b4, Te6edf3secretTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4,
Te6edf3PAYLOAD_TYPE_ACKTb4b4b4, Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4) Tff7b72&Te6edf3ack_hashTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pathTb4b4b4) Te6edf3sendFloodScopedTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3TXT_ACK_DELAYTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendAckToTb4b4b4(Te6edf3fromTb4b4b4, Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4) Tff7b72&Te6edf3ack_hashTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonPeerDataRecv: unsupported message type: %uTa5d6ff"Tb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4) Te6edf3flagsTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_REQ Tff7b72&Tff7b72& Te6edf3len Tff7b72> T79c0ff4Tb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3sender_timestampTb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3sender_timestampTb4b4b4, Te6edf3dataTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4;
Tffa657uint8_t Te6edf3reply_len Tff7b72= Te6edf3onContactRequestTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3sender_timestampTb4b4b4, Tff7b72&Te6edf3dataTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4, Te6edf3len Tff7b72- T79c0ff4Tb4b4b4, Te6edf3temp_bufTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3reply_len Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteFloodTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the response
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3path Tff7b72= Te6edf3createPathReturnTb4b4b4(Te6edf3fromTb4b4b4.Te6edf3idTb4b4b4, Te6edf3secretTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4,
Te6edf3PAYLOAD_TYPE_RESPONSETb4b4b4, Te6edf3temp_bufTb4b4b4, Te6edf3reply_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pathTb4b4b4) Te6edf3sendFloodScopedTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3SERVER_RESPONSE_DELAYTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3reply Tff7b72= Te6edf3createDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_RESPONSETb4b4b4, Te6edf3fromTb4b4b4.Te6edf3idTb4b4b4, Te6edf3secretTb4b4b4, Te6edf3temp_bufTb4b4b4, Te6edf3reply_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3replyTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3fromTb4b4b4.Te6edf3out_path_len Tff7b72!Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{ T8b949e// we have an out_path, so send DIRECT
Te6edf3sendDirectTb4b4b4(Te6edf3replyTb4b4b4, Te6edf3fromTb4b4b4.Te6edf3out_pathTb4b4b4, Te6edf3fromTb4b4b4.Te6edf3out_path_lenTb4b4b4, Te6edf3SERVER_RESPONSE_DELAYTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendFloodScopedTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3replyTb4b4b4, Te6edf3SERVER_RESPONSE_DELAYTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_RESPONSE Tff7b72&Tff7b72& Te6edf3len Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3onContactResponseTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteFloodTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3fromTb4b4b4.Te6edf3out_path_len Tff7b72!Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{
T8b949e// we have direct path, but other node is still sending flood response, so maybe they didn't receive reciprocal path properly(?)
Te6edf3handleReturnPathRetryTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::onPeerPathRecvTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3packetTb4b4b4, Tffa657int Te6edf3sender_idxTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3secretTb4b4b4, Tffa657uint8_tTff7b72* Te6edf3pathTb4b4b4, Tffa657uint8_t Te6edf3path_lenTb4b4b4, Tffa657uint8_t Te6edf3extra_typeTb4b4b4, Tffa657uint8_tTff7b72* Te6edf3extraTb4b4b4, Tffa657uint8_t Te6edf3extra_lenTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3i Tff7b72= Te6edf3matching_peer_indexesTb4b4b4[Te6edf3sender_idxTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3i Tff7b72< T79c0ff0 Tff7b72|Tff7b72| Te6edf3i Tff7b72>Tff7b72= Te6edf3num_contactsTb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonPeerPathRecv: Invalid sender idx: %dTa5d6ff"Tb4b4b4, Te6edf3iTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Te6edf3ContactInfoTff7b72& Te6edf3from Tff7b72= Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tff7b72return Te6edf3onContactPathRecvTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3path_lenTb4b4b4, Te6edf3extra_typeTb4b4b4, Te6edf3extraTb4b4b4, Te6edf3extra_lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::onContactPathRecvTb4b4b4(Te6edf3ContactInfoTff7b72& Te6edf3fromTb4b4b4, Tffa657uint8_tTff7b72* Te6edf3in_pathTb4b4b4, Tffa657uint8_t Te6edf3in_path_lenTb4b4b4, Tffa657uint8_tTff7b72* Te6edf3out_pathTb4b4b4, Tffa657uint8_t Te6edf3out_path_lenTb4b4b4, Tffa657uint8_t Te6edf3extra_typeTb4b4b4, Tffa657uint8_tTff7b72* Te6edf3extraTb4b4b4, Tffa657uint8_t Te6edf3extra_lenTb4b4b4) Tb4b4b4{
T8b949e// NOTE: default impl, we just replace the current 'out_path' regardless, whenever sender sends us a new out_path.
T8b949e// FUTURE: could store multiple out_paths per contact, and try to find which is the 'best'(?)
Te6edf3fromTb4b4b4.Te6edf3out_path_len Tff7b72= Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72:Tff7b72:Te6edf3copyPathTb4b4b4(Te6edf3fromTb4b4b4.Te6edf3out_pathTb4b4b4, Te6edf3out_pathTb4b4b4, Te6edf3out_path_lenTb4b4b4)Tb4b4b4; T8b949e// store a copy of path, for sendDirect()
Te6edf3fromTb4b4b4.Te6edf3lastmod Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3onContactPathUpdatedTb4b4b4(Te6edf3fromTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3extra_type Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_ACK Tff7b72&Tff7b72& Te6edf3extra_len Tff7b72>Tff7b72= T79c0ff4Tb4b4b4) Tb4b4b4{
T8b949e// also got an encoded ACK!
Tff7b72if Tb4b4b4(Te6edf3processAckTb4b4b4(Te6edf3extraTb4b4b4) Tff7b72!Tff7b72= Tffa657NULLTb4b4b4) Tb4b4b4{
Te6edf3txt_send_timeout Tff7b72= T79c0ff0Tb4b4b4; T8b949e// matched one we're waiting for, cancel timeout timer
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3extra_type Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_RESPONSE Tff7b72&Tff7b72& Te6edf3extra_len Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3onContactResponseTb4b4b4(Te6edf3fromTb4b4b4, Te6edf3extraTb4b4b4, Te6edf3extra_lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657trueTb4b4b4; T8b949e// send reciprocal path if necessary
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::onAckRecvTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3packetTb4b4b4, Tffa657uint32_t Te6edf3ack_crcTb4b4b4) Tb4b4b4{
Te6edf3ContactInfoTff7b72* Te6edf3fromTb4b4b4;
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3from Tff7b72= Te6edf3processAckTb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4)Tff7b72&Te6edf3ack_crcTb4b4b4)Tb4b4b4) Tff7b72!Tff7b72= Tffa657NULLTb4b4b4) Tb4b4b4{
Te6edf3txt_send_timeout Tff7b72= T79c0ff0Tb4b4b4; T8b949e// matched one we're waiting for, cancel timeout timer
Te6edf3packetTff7b72-Tff7b72>Te6edf3markDoNotRetransmitTb4b4b4(Tb4b4b4)Tb4b4b4; T8b949e// ACK was for this node, so don't retransmit
Tff7b72if Tb4b4b4(Te6edf3packetTff7b72-Tff7b72>Te6edf3isRouteFloodTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3fromTff7b72-Tff7b72>Te6edf3out_path_len Tff7b72!Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{
T8b949e// we have direct path, but other node is still sending flood, so maybe they didn't receive reciprocal path properly(?)
Te6edf3handleReturnPathRetryTb4b4b4(Tff7b72*Te6edf3fromTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3pathTb4b4b4, Te6edf3packetTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::handleReturnPathRetryTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3contactTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3pathTb4b4b4, Tffa657uint8_t Te6edf3path_lenTb4b4b4) Tb4b4b4{
T8b949e// NOTE: simplest impl is just to re-send a reciprocal return path to sender (DIRECTLY)
T8b949e// override this method in various firmwares, if there's a better strategy
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3rpath Tff7b72= Te6edf3createPathReturnTb4b4b4(Te6edf3contactTb4b4b4.Te6edf3idTb4b4b4, Te6edf3contactTb4b4b4.Te6edf3getSharedSecretTb4b4b4(Te6edf3self_idTb4b4b4)Tb4b4b4, Te6edf3pathTb4b4b4, Te6edf3path_lenTb4b4b4, T79c0ff0Tb4b4b4, Tffa657NULLTb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3rpathTb4b4b4) Te6edf3sendDirectTb4b4b4(Te6edf3rpathTb4b4b4, Te6edf3contactTb4b4b4.Te6edf3out_pathTb4b4b4, Te6edf3contactTb4b4b4.Te6edf3out_path_lenTb4b4b4, T79c0ff3000Tb4b4b4)Tb4b4b4; T8b949e// 3 second delay
Tb4b4b4}
Tff7b72#Tff7b72ifdef MAX_GROUP_CHANNELS
Tffa657int Td2a8ffBaseChatMesh::searchChannelsByHashTb4b4b4(Tff7b72const Tffa657uint8_tTff7b72* Te6edf3hashTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3GroupChannel Te6edf3destTb4b4b4[Tb4b4b4]Tb4b4b4, Tffa657int Te6edf3max_matchesTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3n Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_GROUP_CHANNELS Tff7b72&Tff7b72& Te6edf3n Tff7b72< Te6edf3max_matchesTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3channelsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3channelTb4b4b4.Te6edf3hashTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72=Tff7b72= Te6edf3hashTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4) Tb4b4b4{
Te6edf3destTb4b4b4[Te6edf3nTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3channelsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3channelTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72return Te6edf3nTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tffa657void Td2a8ffBaseChatMesh::onGroupDataRecvTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3packetTb4b4b4, Tffa657uint8_t Te6edf3typeTb4b4b4, Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3GroupChannelTff7b72& Te6edf3channelTb4b4b4, Tffa657uint8_tTff7b72* Te6edf3dataTb4b4b4, Tffa657size_t Te6edf3lenTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_GRP_TXTTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3len Tff7b72< T79c0ff5Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonGroupDataRecv: dropping short group text payload len=%dTa5d6ff"Tb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3lenTb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tffa657uint8_t Te6edf3txt_type Tff7b72= Te6edf3dataTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3txt_type Tff7b72>Tff7b72> T79c0ff2Tb4b4b4) Tff7b72!Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonGroupDataRecv: dropping unsupported group text type=%dTa5d6ff"Tb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3txt_typeTb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tffa657uint32_t Te6edf3timestampTb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3timestampTb4b4b4, Te6edf3dataTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4;
T8b949e// len can be > original length, but 'text' will be padded with zeroes
Te6edf3dataTb4b4b4[Te6edf3lenTb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// need to make a C string again, with null terminator
T8b949e// notify UI of this new message
Te6edf3onChannelMessageRecvTb4b4b4(Te6edf3channelTb4b4b4, Te6edf3packetTb4b4b4, Te6edf3timestampTb4b4b4, Tb4b4b4(Tff7b72const Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3dataTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4)Tb4b4b4; T8b949e// let UI know
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_GRP_DATATb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3len Tff7b72< T79c0ff3Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonGroupDataRecv: dropping short group data payload len=%dTa5d6ff"Tb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3lenTb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tffa657uint16_t Te6edf3data_type Tff7b72= Tb4b4b4(Tb4b4b4(Tffa657uint16_tTb4b4b4)Te6edf3dataTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4) Tff7b72| Tb4b4b4(Tb4b4b4(Tb4b4b4(Tffa657uint16_tTb4b4b4)Te6edf3dataTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4) Tff7b72<Tff7b72< T79c0ff8Tb4b4b4)Tb4b4b4;
Tffa657uint8_t Te6edf3data_len Tff7b72= Te6edf3dataTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4;
Tffa657size_t Te6edf3available_len Tff7b72= Te6edf3len Tff7b72- T79c0ff3Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3data_len Tff7b72> Te6edf3available_lenTb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffonGroupDataRecv: dropping malformed group data type=%d len=%d available=%dTa5d6ff"Tb4b4b4,
Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3data_typeTb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3data_lenTb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3available_lenTb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3onChannelDataRecvTb4b4b4(Te6edf3channelTb4b4b4, Te6edf3packetTb4b4b4, Te6edf3data_typeTb4b4b4, Tff7b72&Te6edf3dataTb4b4b4[T79c0ff3Tb4b4b4]Tb4b4b4, Te6edf3data_lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Td2a8ffBaseChatMesh::composeMsgPacketTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3recipientTb4b4b4, Tffa657uint32_t Te6edf3timestampTb4b4b4, Tffa657uint8_t Te6edf3attemptTb4b4b4, Tff7b72const Tffa657char Tff7b72*Te6edf3textTb4b4b4, Tffa657uint32_tTff7b72& Te6edf3expected_ackTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3text_len Tff7b72= Te6edf3strlenTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3text_len Tff7b72> Te6edf3MAX_TEXT_LENTb4b4b4) Tff7b72return Tffa657NULLTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3attempt Tff7b72> T79c0ff3 Tff7b72&Tff7b72& Te6edf3text_len Tff7b72> Te6edf3MAX_TEXT_LENT79c0ff-2Tb4b4b4) Tff7b72return Tffa657NULLTb4b4b4;
Tffa657uint8_t Te6edf3tempTb4b4b4[T79c0ff5Tff7b72+Te6edf3MAX_TEXT_LENTff7b72+T79c0ff1Tb4b4b4]Tb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3tempTb4b4b4, Tff7b72&Te6edf3timestampTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// mostly an extra blob to help make packet_hash unique
Te6edf3tempTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72= Tb4b4b4(Te6edf3attempt Tff7b72& T79c0ff3Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3tempTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4, Te6edf3textTb4b4b4, Te6edf3text_len Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4;
T8b949e// calc expected ACK reply
Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3sha256Tb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4)Tff7b72&Te6edf3expected_ackTb4b4b4, T79c0ff4Tb4b4b4, Te6edf3tempTb4b4b4, T79c0ff5 Tff7b72+ Te6edf3text_lenTb4b4b4, Te6edf3self_idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Tffa657int Te6edf3len Tff7b72= T79c0ff5 Tff7b72+ Te6edf3text_lenTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3attempt Tff7b72> T79c0ff3Tb4b4b4) Tb4b4b4{
Te6edf3tempTb4b4b4[Te6edf3lenTff7b72+Tff7b72+Tb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// null terminator
Te6edf3tempTb4b4b4[Te6edf3lenTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3attemptTb4b4b4; T8b949e// hide attempt number at tail end of payload
Tb4b4b4}
Tff7b72return Te6edf3createDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_TXT_MSGTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3idTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3getSharedSecretTb4b4b4(Te6edf3self_idTb4b4b4)Tb4b4b4, Te6edf3tempTb4b4b4, Te6edf3lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657int Td2a8ffBaseChatMesh::sendMessageTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3recipientTb4b4b4, Tffa657uint32_t Te6edf3timestampTb4b4b4, Tffa657uint8_t Te6edf3attemptTb4b4b4, Tff7b72const Tffa657charTff7b72* Te6edf3textTb4b4b4, Tffa657uint32_tTff7b72& Te6edf3expected_ackTb4b4b4, Tffa657uint32_tTff7b72& Te6edf3est_timeoutTb4b4b4) Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3pkt Tff7b72= Te6edf3composeMsgPacketTb4b4b4(Te6edf3recipientTb4b4b4, Te6edf3timestampTb4b4b4, Te6edf3attemptTb4b4b4, Te6edf3textTb4b4b4, Te6edf3expected_ackTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pkt Tff7b72=Tff7b72= Tffa657NULLTb4b4b4) Tff7b72return Te6edf3MSG_SEND_FAILEDTb4b4b4;
Tffa657uint32_t Te6edf3t Tff7b72= Te6edf3_radioTff7b72-Tff7b72>Te6edf3getEstAirtimeForTb4b4b4(Te6edf3pktTff7b72-Tff7b72>Te6edf3getRawLengthTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tffa657int Te6edf3rcTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3recipientTb4b4b4.Te6edf3out_path_len Tff7b72=Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{
Te6edf3sendFloodScopedTb4b4b4(Te6edf3recipientTb4b4b4, Te6edf3pktTb4b4b4)Tb4b4b4;
Te6edf3txt_send_timeout Tff7b72= Te6edf3futureMillisTb4b4b4(Te6edf3est_timeout Tff7b72= Te6edf3calcFloodTimeoutMillisForTb4b4b4(Te6edf3tTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3rc Tff7b72= Te6edf3MSG_SEND_SENT_FLOODTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendDirectTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_pathTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_path_lenTb4b4b4)Tb4b4b4;
Te6edf3txt_send_timeout Tff7b72= Te6edf3futureMillisTb4b4b4(Te6edf3est_timeout Tff7b72= Te6edf3calcDirectTimeoutMillisForTb4b4b4(Te6edf3tTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_path_lenTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3rc Tff7b72= Te6edf3MSG_SEND_SENT_DIRECTTb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3rcTb4b4b4;
Tb4b4b4}
Tffa657int Td2a8ffBaseChatMesh::sendCommandDataTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3recipientTb4b4b4, Tffa657uint32_t Te6edf3timestampTb4b4b4, Tffa657uint8_t Te6edf3attemptTb4b4b4, Tff7b72const Tffa657charTff7b72* Te6edf3textTb4b4b4, Tffa657uint32_tTff7b72& Te6edf3est_timeoutTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3text_len Tff7b72= Te6edf3strlenTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3text_len Tff7b72> Te6edf3MAX_TEXT_LENTb4b4b4) Tff7b72return Te6edf3MSG_SEND_FAILEDTb4b4b4;
Tffa657uint8_t Te6edf3tempTb4b4b4[T79c0ff5Tff7b72+Te6edf3MAX_TEXT_LENTff7b72+T79c0ff1Tb4b4b4]Tb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3tempTb4b4b4, Tff7b72&Te6edf3timestampTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// mostly an extra blob to help make packet_hash unique
Te6edf3tempTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72= Tb4b4b4(Te6edf3attempt Tff7b72& T79c0ff3Tb4b4b4) Tff7b72| Tb4b4b4(Te6edf3TXT_TYPE_CLI_DATA Tff7b72<Tff7b72< T79c0ff2Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3tempTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4, Te6edf3textTb4b4b4, Te6edf3text_len Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3pkt Tff7b72= Te6edf3createDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_TXT_MSGTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3idTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3getSharedSecretTb4b4b4(Te6edf3self_idTb4b4b4)Tb4b4b4, Te6edf3tempTb4b4b4, T79c0ff5 Tff7b72+ Te6edf3text_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pkt Tff7b72=Tff7b72= Tffa657NULLTb4b4b4) Tff7b72return Te6edf3MSG_SEND_FAILEDTb4b4b4;
Tffa657uint32_t Te6edf3t Tff7b72= Te6edf3_radioTff7b72-Tff7b72>Te6edf3getEstAirtimeForTb4b4b4(Te6edf3pktTff7b72-Tff7b72>Te6edf3getRawLengthTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tffa657int Te6edf3rcTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3recipientTb4b4b4.Te6edf3out_path_len Tff7b72=Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{
Te6edf3sendFloodScopedTb4b4b4(Te6edf3recipientTb4b4b4, Te6edf3pktTb4b4b4)Tb4b4b4;
Te6edf3txt_send_timeout Tff7b72= Te6edf3futureMillisTb4b4b4(Te6edf3est_timeout Tff7b72= Te6edf3calcFloodTimeoutMillisForTb4b4b4(Te6edf3tTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3rc Tff7b72= Te6edf3MSG_SEND_SENT_FLOODTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendDirectTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_pathTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_path_lenTb4b4b4)Tb4b4b4;
Te6edf3txt_send_timeout Tff7b72= Te6edf3futureMillisTb4b4b4(Te6edf3est_timeout Tff7b72= Te6edf3calcDirectTimeoutMillisForTb4b4b4(Te6edf3tTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_path_lenTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3rc Tff7b72= Te6edf3MSG_SEND_SENT_DIRECTTb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3rcTb4b4b4;
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::sendGroupMessageTb4b4b4(Tffa657uint32_t Te6edf3timestampTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3GroupChannelTff7b72& Te6edf3channelTb4b4b4, Tff7b72const Tffa657charTff7b72* Te6edf3sender_nameTb4b4b4, Tff7b72const Tffa657charTff7b72* Te6edf3textTb4b4b4, Tffa657int Te6edf3text_lenTb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3tempTb4b4b4[T79c0ff5Tff7b72+Te6edf3MAX_TEXT_LENTff7b72+T79c0ff32Tb4b4b4]Tb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3tempTb4b4b4, Tff7b72&Te6edf3timestampTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// mostly an extra blob to help make packet_hash unique
Te6edf3tempTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// TXT_TYPE_PLAIN
Te6edf3sprintfTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3tempTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4, Ta5d6ff"Ta5d6ff%s: Ta5d6ff"Tb4b4b4, Te6edf3sender_nameTb4b4b4)Tb4b4b4; T8b949e// <sender>: <msg>
Tffa657char Tff7b72*Te6edf3ep Tff7b72= Te6edf3strchrTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3tempTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4;
Tffa657int Te6edf3prefix_len Tff7b72= Te6edf3ep Tff7b72- Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3tempTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3text_len Tff7b72+ Te6edf3prefix_len Tff7b72> Te6edf3MAX_TEXT_LENTb4b4b4) Te6edf3text_len Tff7b72= Te6edf3MAX_TEXT_LEN Tff7b72- Te6edf3prefix_lenTb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3epTb4b4b4, Te6edf3textTb4b4b4, Te6edf3text_lenTb4b4b4)Tb4b4b4;
Te6edf3epTb4b4b4[Te6edf3text_lenTb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// null terminator
Tff7b72auto Te6edf3pkt Tff7b72= Te6edf3createGroupDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_GRP_TXTTb4b4b4, Te6edf3channelTb4b4b4, Te6edf3tempTb4b4b4, T79c0ff5 Tff7b72+ Te6edf3prefix_len Tff7b72+ Te6edf3text_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Tb4b4b4{
Te6edf3sendFloodScopedTb4b4b4(Te6edf3channelTb4b4b4, Te6edf3pktTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::sendGroupDataTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3GroupChannelTff7b72& Te6edf3channelTb4b4b4, Tffa657uint8_tTff7b72* Te6edf3pathTb4b4b4, Tffa657uint8_t Te6edf3path_lenTb4b4b4, Tffa657uint16_t Te6edf3data_typeTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3dataTb4b4b4, Tffa657int Te6edf3data_lenTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3data_len Tff7b72< T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffsendGroupData: invalid negative data_len=%dTa5d6ff"Tb4b4b4, Te6edf3data_lenTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3data_len Tff7b72> Te6edf3MAX_GROUP_DATA_LENGTHTb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffsendGroupData: data_len=%d exceeds max=%dTa5d6ff"Tb4b4b4, Te6edf3data_lenTb4b4b4, Te6edf3MAX_GROUP_DATA_LENGTHTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tffa657uint8_t Te6edf3tempTb4b4b4[T79c0ff3 Tff7b72+ Te6edf3MAX_GROUP_DATA_LENGTHTb4b4b4]Tb4b4b4;
Te6edf3tempTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72= Tb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4(Te6edf3data_type Tff7b72& T79c0ff0xFFTb4b4b4)Tb4b4b4;
Te6edf3tempTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72= Tb4b4b4(Tffa657uint8_tTb4b4b4)Tb4b4b4(Te6edf3data_type Tff7b72>Tff7b72> T79c0ff8Tb4b4b4)Tb4b4b4;
Te6edf3tempTb4b4b4[T79c0ff2Tb4b4b4] Tff7b72= Tb4b4b4(Tffa657uint8_tTb4b4b4)Te6edf3data_lenTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3data_len Tff7b72> T79c0ff0Tb4b4b4) Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3tempTb4b4b4[T79c0ff3Tb4b4b4]Tb4b4b4, Te6edf3dataTb4b4b4, Te6edf3data_lenTb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3pkt Tff7b72= Te6edf3createGroupDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_GRP_DATATb4b4b4, Te6edf3channelTb4b4b4, Te6edf3tempTb4b4b4, T79c0ff3 Tff7b72+ Te6edf3data_lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pkt Tff7b72=Tff7b72= Tffa657NULLTb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffsendGroupData: unable to create group datagram, data_len=%dTa5d6ff"Tb4b4b4, Te6edf3data_lenTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3path_len Tff7b72=Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{
Te6edf3sendFloodScopedTb4b4b4(Te6edf3channelTb4b4b4, Te6edf3pktTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendDirectTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3path_lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::shareContactZeroHopTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3contactTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3plen Tff7b72= Te6edf3getBlobByKeyTb4b4b4(Te6edf3contactTb4b4b4.Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4, Te6edf3temp_bufTb4b4b4)Tb4b4b4; T8b949e// retrieve last raw advert packet
Tff7b72if Tb4b4b4(Te6edf3plen Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tff7b72return Tffa657falseTb4b4b4; T8b949e// not found
Tff7b72auto Te6edf3packet Tff7b72= Te6edf3obtainNewPacketTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3packet Tff7b72=Tff7b72= Tffa657NULLTb4b4b4) Tff7b72return Tffa657falseTb4b4b4; T8b949e// no Packets available
Te6edf3packetTff7b72-Tff7b72>Te6edf3readFromTb4b4b4(Te6edf3temp_bufTb4b4b4, Te6edf3plenTb4b4b4)Tb4b4b4; T8b949e// restore Packet from 'blob'
Tffa657uint16_t Te6edf3codesTb4b4b4[T79c0ff2Tb4b4b4]Tb4b4b4;
Te6edf3codesTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72= Te6edf3codesTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// { 0, 0 } means 'send this nowhere'
Te6edf3sendZeroHopTb4b4b4(Te6edf3packetTb4b4b4, Te6edf3codesTb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4; T8b949e// success
Tb4b4b4}
Tffa657uint8_t Td2a8ffBaseChatMesh::exportContactTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3contactTb4b4b4, Tffa657uint8_t Te6edf3dest_bufTb4b4b4[Tb4b4b4]Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3getBlobByKeyTb4b4b4(Te6edf3contactTb4b4b4.Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4, Te6edf3dest_bufTb4b4b4)Tb4b4b4; T8b949e// retrieve last raw advert packet
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::importContactTb4b4b4(Tff7b72const Tffa657uint8_t Te6edf3src_bufTb4b4b4[Tb4b4b4]Tb4b4b4, Tffa657uint8_t Te6edf3lenTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3pkt Tff7b72= Te6edf3obtainNewPacketTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3pktTff7b72-Tff7b72>Te6edf3readFromTb4b4b4(Te6edf3src_bufTb4b4b4, Te6edf3lenTb4b4b4) Tff7b72&Tff7b72& Te6edf3pktTff7b72-Tff7b72>Te6edf3getPayloadTypeTb4b4b4(Tb4b4b4) Tff7b72=Tff7b72= Te6edf3PAYLOAD_TYPE_ADVERTTb4b4b4) Tb4b4b4{
Te6edf3pktTff7b72-Tff7b72>Te6edf3header Tff7b72|Tff7b72= Te6edf3ROUTE_TYPE_FLOODTb4b4b4; T8b949e// simulate it being received flood-mode
Te6edf3getTablesTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3clearTb4b4b4(Te6edf3pktTb4b4b4)Tb4b4b4; T8b949e// remove packet hash from table, so we can receive/process it again
Te6edf3_pendingLoopback Tff7b72= Te6edf3pktTb4b4b4; T8b949e// loop-back, as if received over radio
Tff7b72return Tffa657trueTb4b4b4; T8b949e// success
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3releasePacketTb4b4b4(Te6edf3pktTb4b4b4)Tb4b4b4; T8b949e// undo the obtainNewPacket()
Tb4b4b4}
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4; T8b949e// error
Tb4b4b4}
Tffa657int Td2a8ffBaseChatMesh::sendLoginTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3recipientTb4b4b4, Tff7b72const Tffa657charTff7b72* Te6edf3passwordTb4b4b4, Tffa657uint32_tTff7b72& Te6edf3est_timeoutTb4b4b4) Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3pktTb4b4b4;
Tb4b4b4{
Tffa657int Te6edf3tlenTb4b4b4;
Tffa657uint8_t Te6edf3tempTb4b4b4[T79c0ff24Tb4b4b4]Tb4b4b4;
Tffa657uint32_t Te6edf3now Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeUniqueTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3tempTb4b4b4, Tff7b72&Te6edf3nowTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// mostly an extra blob to help make packet_hash unique
Tff7b72if Tb4b4b4(Te6edf3recipientTb4b4b4.Te6edf3type Tff7b72=Tff7b72= Te6edf3ADV_TYPE_ROOMTb4b4b4) Tb4b4b4{
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3tempTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4, Tff7b72&Te6edf3recipientTb4b4b4.Te6edf3sync_sinceTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4;
Tffa657int Te6edf3len Tff7b72= Te6edf3strlenTb4b4b4(Te6edf3passwordTb4b4b4)Tb4b4b4; Tff7b72if Tb4b4b4(Te6edf3len Tff7b72> T79c0ff15Tb4b4b4) Te6edf3len Tff7b72= T79c0ff15Tb4b4b4; T8b949e// max 15 chars currently
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3tempTb4b4b4[T79c0ff8Tb4b4b4]Tb4b4b4, Te6edf3passwordTb4b4b4, Te6edf3lenTb4b4b4)Tb4b4b4;
Te6edf3tlen Tff7b72= T79c0ff8 Tff7b72+ Te6edf3lenTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tffa657int Te6edf3len Tff7b72= Te6edf3strlenTb4b4b4(Te6edf3passwordTb4b4b4)Tb4b4b4; Tff7b72if Tb4b4b4(Te6edf3len Tff7b72> T79c0ff15Tb4b4b4) Te6edf3len Tff7b72= T79c0ff15Tb4b4b4; T8b949e// max 15 chars currently
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3tempTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4, Te6edf3passwordTb4b4b4, Te6edf3lenTb4b4b4)Tb4b4b4;
Te6edf3tlen Tff7b72= T79c0ff4 Tff7b72+ Te6edf3lenTb4b4b4;
Tb4b4b4}
Te6edf3pkt Tff7b72= Te6edf3createAnonDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_ANON_REQTb4b4b4, Te6edf3self_idTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3idTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3getSharedSecretTb4b4b4(Te6edf3self_idTb4b4b4)Tb4b4b4, Te6edf3tempTb4b4b4, Te6edf3tlenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3t Tff7b72= Te6edf3_radioTff7b72-Tff7b72>Te6edf3getEstAirtimeForTb4b4b4(Te6edf3pktTff7b72-Tff7b72>Te6edf3getRawLengthTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3recipientTb4b4b4.Te6edf3out_path_len Tff7b72=Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{
Te6edf3sendFloodScopedTb4b4b4(Te6edf3recipientTb4b4b4, Te6edf3pktTb4b4b4)Tb4b4b4;
Te6edf3est_timeout Tff7b72= Te6edf3calcFloodTimeoutMillisForTb4b4b4(Te6edf3tTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3MSG_SEND_SENT_FLOODTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendDirectTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_pathTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_path_lenTb4b4b4)Tb4b4b4;
Te6edf3est_timeout Tff7b72= Te6edf3calcDirectTimeoutMillisForTb4b4b4(Te6edf3tTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_path_lenTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3MSG_SEND_SENT_DIRECTTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72return Te6edf3MSG_SEND_FAILEDTb4b4b4;
Tb4b4b4}
Tffa657int Td2a8ffBaseChatMesh::sendAnonReqTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3recipientTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3dataTb4b4b4, Tffa657uint8_t Te6edf3lenTb4b4b4, Tffa657uint32_tTff7b72& Te6edf3tagTb4b4b4, Tffa657uint32_tTff7b72& Te6edf3est_timeoutTb4b4b4) Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3pktTb4b4b4;
Tb4b4b4{
Tffa657uint8_t Te6edf3tempTb4b4b4[Te6edf3MAX_PACKET_PAYLOADTb4b4b4]Tb4b4b4;
Te6edf3tag Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeUniqueTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3tempTb4b4b4, Tff7b72&Te6edf3tagTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// tag to match later (also extra blob to help make packet_hash unique)
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3tempTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4, Te6edf3dataTb4b4b4, Te6edf3lenTb4b4b4)Tb4b4b4;
Te6edf3pkt Tff7b72= Te6edf3createAnonDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_ANON_REQTb4b4b4, Te6edf3self_idTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3idTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3getSharedSecretTb4b4b4(Te6edf3self_idTb4b4b4)Tb4b4b4, Te6edf3tempTb4b4b4, T79c0ff4 Tff7b72+ Te6edf3lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3t Tff7b72= Te6edf3_radioTff7b72-Tff7b72>Te6edf3getEstAirtimeForTb4b4b4(Te6edf3pktTff7b72-Tff7b72>Te6edf3getRawLengthTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3recipientTb4b4b4.Te6edf3out_path_len Tff7b72=Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{
Te6edf3sendFloodScopedTb4b4b4(Te6edf3recipientTb4b4b4, Te6edf3pktTb4b4b4)Tb4b4b4;
Te6edf3est_timeout Tff7b72= Te6edf3calcFloodTimeoutMillisForTb4b4b4(Te6edf3tTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3MSG_SEND_SENT_FLOODTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendDirectTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_pathTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_path_lenTb4b4b4)Tb4b4b4;
Te6edf3est_timeout Tff7b72= Te6edf3calcDirectTimeoutMillisForTb4b4b4(Te6edf3tTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_path_lenTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3MSG_SEND_SENT_DIRECTTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72return Te6edf3MSG_SEND_FAILEDTb4b4b4;
Tb4b4b4}
Tffa657int Td2a8ffBaseChatMesh::sendRequestTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3recipientTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3req_dataTb4b4b4, Tffa657uint8_t Te6edf3data_lenTb4b4b4, Tffa657uint32_tTff7b72& Te6edf3tagTb4b4b4, Tffa657uint32_tTff7b72& Te6edf3est_timeoutTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3data_len Tff7b72> Te6edf3MAX_PACKET_PAYLOAD Tff7b72- T79c0ff16Tb4b4b4) Tff7b72return Te6edf3MSG_SEND_FAILEDTb4b4b4;
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3pktTb4b4b4;
Tb4b4b4{
Tffa657uint8_t Te6edf3tempTb4b4b4[Te6edf3MAX_PACKET_PAYLOADTb4b4b4]Tb4b4b4;
Te6edf3tag Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeUniqueTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3tempTb4b4b4, Tff7b72&Te6edf3tagTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// mostly an extra blob to help make packet_hash unique
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3tempTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4, Te6edf3req_dataTb4b4b4, Te6edf3data_lenTb4b4b4)Tb4b4b4;
Te6edf3pkt Tff7b72= Te6edf3createDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_REQTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3idTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3getSharedSecretTb4b4b4(Te6edf3self_idTb4b4b4)Tb4b4b4, Te6edf3tempTb4b4b4, T79c0ff4 Tff7b72+ Te6edf3data_lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3t Tff7b72= Te6edf3_radioTff7b72-Tff7b72>Te6edf3getEstAirtimeForTb4b4b4(Te6edf3pktTff7b72-Tff7b72>Te6edf3getRawLengthTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3recipientTb4b4b4.Te6edf3out_path_len Tff7b72=Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{
Te6edf3sendFloodScopedTb4b4b4(Te6edf3recipientTb4b4b4, Te6edf3pktTb4b4b4)Tb4b4b4;
Te6edf3est_timeout Tff7b72= Te6edf3calcFloodTimeoutMillisForTb4b4b4(Te6edf3tTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3MSG_SEND_SENT_FLOODTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendDirectTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_pathTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_path_lenTb4b4b4)Tb4b4b4;
Te6edf3est_timeout Tff7b72= Te6edf3calcDirectTimeoutMillisForTb4b4b4(Te6edf3tTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_path_lenTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3MSG_SEND_SENT_DIRECTTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72return Te6edf3MSG_SEND_FAILEDTb4b4b4;
Tb4b4b4}
Tffa657int Td2a8ffBaseChatMesh::sendRequestTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3recipientTb4b4b4, Tffa657uint8_t Te6edf3req_typeTb4b4b4, Tffa657uint32_tTff7b72& Te6edf3tagTb4b4b4, Tffa657uint32_tTff7b72& Te6edf3est_timeoutTb4b4b4) Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3pktTb4b4b4;
Tb4b4b4{
Tffa657uint8_t Te6edf3tempTb4b4b4[T79c0ff13Tb4b4b4]Tb4b4b4;
Te6edf3tag Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeUniqueTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3tempTb4b4b4, Tff7b72&Te6edf3tagTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// mostly an extra blob to help make packet_hash unique
Te6edf3tempTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72= Te6edf3req_typeTb4b4b4;
Te6edf3memsetTb4b4b4(Tff7b72&Te6edf3tempTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4, T79c0ff0Tb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// reserved (possibly for 'since' param)
Te6edf3getRNGTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3randomTb4b4b4(Tff7b72&Te6edf3tempTb4b4b4[T79c0ff9Tb4b4b4]Tb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// random blob to help make packet-hash unique
Te6edf3pkt Tff7b72= Te6edf3createDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_REQTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3idTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3getSharedSecretTb4b4b4(Te6edf3self_idTb4b4b4)Tb4b4b4, Te6edf3tempTb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3tempTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3t Tff7b72= Te6edf3_radioTff7b72-Tff7b72>Te6edf3getEstAirtimeForTb4b4b4(Te6edf3pktTff7b72-Tff7b72>Te6edf3getRawLengthTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3recipientTb4b4b4.Te6edf3out_path_len Tff7b72=Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{
Te6edf3sendFloodScopedTb4b4b4(Te6edf3recipientTb4b4b4, Te6edf3pktTb4b4b4)Tb4b4b4;
Te6edf3est_timeout Tff7b72= Te6edf3calcFloodTimeoutMillisForTb4b4b4(Te6edf3tTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3MSG_SEND_SENT_FLOODTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendDirectTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_pathTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_path_lenTb4b4b4)Tb4b4b4;
Te6edf3est_timeout Tff7b72= Te6edf3calcDirectTimeoutMillisForTb4b4b4(Te6edf3tTb4b4b4, Te6edf3recipientTb4b4b4.Te6edf3out_path_lenTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3MSG_SEND_SENT_DIRECTTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72return Te6edf3MSG_SEND_FAILEDTb4b4b4;
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::startConnectionTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3contactTb4b4b4, Tffa657uint16_t Te6edf3keep_alive_secsTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3use_idx Tff7b72= T79c0ff-1Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_CONNECTIONSTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3keep_alive_millis Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// free slot?
Te6edf3use_idx Tff7b72= Te6edf3iTb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3server_idTb4b4b4.Te6edf3matchesTb4b4b4(Te6edf3contactTb4b4b4.Te6edf3idTb4b4b4)Tb4b4b4) Tb4b4b4{ T8b949e// already in table?
Te6edf3use_idx Tff7b72= Te6edf3iTb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3use_idx Tff7b72< T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4; T8b949e// table is full
Tb4b4b4}
Te6edf3connectionsTb4b4b4[Te6edf3use_idxTb4b4b4]Tb4b4b4.Te6edf3server_id Tff7b72= Te6edf3contactTb4b4b4.Te6edf3idTb4b4b4;
Tffa657uint32_t Te6edf3interval Tff7b72= Te6edf3connectionsTb4b4b4[Te6edf3use_idxTb4b4b4]Tb4b4b4.Te6edf3keep_alive_millis Tff7b72= Tb4b4b4(Tb4b4b4(Tffa657uint32_tTb4b4b4)Te6edf3keep_alive_secsTb4b4b4)Tff7b72*T79c0ff1000Tb4b4b4;
Te6edf3connectionsTb4b4b4[Te6edf3use_idxTb4b4b4]Tb4b4b4.Te6edf3next_ping Tff7b72= Te6edf3futureMillisTb4b4b4(Te6edf3intervalTb4b4b4)Tb4b4b4;
Te6edf3connectionsTb4b4b4[Te6edf3use_idxTb4b4b4]Tb4b4b4.Te6edf3expected_ack Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3connectionsTb4b4b4[Te6edf3use_idxTb4b4b4]Tb4b4b4.Te6edf3last_activity Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4; T8b949e// success
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::stopConnectionTb4b4b4(Tff7b72const Tffa657uint8_tTff7b72* Te6edf3pub_keyTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_CONNECTIONSTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3server_idTb4b4b4.Te6edf3matchesTb4b4b4(Te6edf3pub_keyTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3keep_alive_millis Tff7b72= T79c0ff0Tb4b4b4; T8b949e// mark slot as now free
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3next_ping Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3expected_ack Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3last_activity Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::hasConnectionToTb4b4b4(Tff7b72const Tffa657uint8_tTff7b72* Te6edf3pub_keyTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_CONNECTIONSTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3keep_alive_millis Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3server_idTb4b4b4.Te6edf3matchesTb4b4b4(Te6edf3pub_keyTb4b4b4)Tb4b4b4) Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::markConnectionActiveTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3contactTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_CONNECTIONSTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3keep_alive_millis Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3server_idTb4b4b4.Te6edf3matchesTb4b4b4(Te6edf3contactTb4b4b4.Te6edf3idTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3last_activity Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// re-schedule next KEEP_ALIVE, now that we have heard from server
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3next_ping Tff7b72= Te6edf3futureMillisTb4b4b4(Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3keep_alive_millisTb4b4b4)Tb4b4b4;
Tff7b72breakTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3ContactInfoTff7b72* Td2a8ffBaseChatMesh::checkConnectionsAckTb4b4b4(Tff7b72const Tffa657uint8_tTff7b72* Te6edf3dataTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_CONNECTIONSTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3keep_alive_millis Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3memcmpTb4b4b4(Tff7b72&Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3expected_ackTb4b4b4, Te6edf3dataTb4b4b4, T79c0ff4Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
T8b949e// yes, got an ack for our keep_alive request!
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3expected_ack Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3last_activity Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// re-schedule next KEEP_ALIVE, now that we have heard from server
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3next_ping Tff7b72= Te6edf3futureMillisTb4b4b4(Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3keep_alive_millisTb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3id Tff7b72= Tff7b72&Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3server_idTb4b4b4;
Tff7b72return Te6edf3lookupContactByPubKeyTb4b4b4(Te6edf3idTff7b72-Tff7b72>Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4; T8b949e// yes, a match
Tb4b4b4}
Tb4b4b4}
Tff7b72return Tffa657NULLTb4b4b4; T8b949e/// no match
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::checkConnectionsTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// scan connections[] table, send KEEP_ALIVE requests
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_CONNECTIONSTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3keep_alive_millis Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tff7b72continueTb4b4b4; T8b949e// unused slot
Tffa657uint32_t Te6edf3now Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657uint32_t Te6edf3expire_secs Tff7b72= Tb4b4b4(Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3keep_alive_millis Tff7b72/ T79c0ff1000Tb4b4b4) Tff7b72* T79c0ff5 Tff7b72/ T79c0ff2Tb4b4b4; T8b949e// 2.5 x keep_alive interval
Tff7b72if Tb4b4b4(Te6edf3now Tff7b72>Tff7b72= Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3last_activity Tff7b72+ Te6edf3expire_secsTb4b4b4) Tb4b4b4{
T8b949e// connection now lost
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3keep_alive_millis Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3next_ping Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3expected_ack Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3last_activity Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72continueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3millisHasNowPassedTb4b4b4(Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3next_pingTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3contact Tff7b72= Te6edf3lookupContactByPubKeyTb4b4b4(Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3server_idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3contact Tff7b72=Tff7b72= Tffa657NULLTb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffcheckConnections(): Keep_alive contact not found!Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72continueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3contactTff7b72-Tff7b72>Te6edf3out_path_len Tff7b72=Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4) Tb4b4b4{
Te6edf3MESH_DEBUG_PRINTLNTb4b4b4(Ta5d6ff"Ta5d6ffcheckConnections(): Keep_alive contact, no out_path!Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72continueTb4b4b4;
Tb4b4b4}
T8b949e// send KEEP_ALIVE request
Tffa657uint8_t Te6edf3dataTb4b4b4[T79c0ff9Tb4b4b4]Tb4b4b4;
Tffa657uint32_t Te6edf3now Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeUniqueTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3dataTb4b4b4, Tff7b72&Te6edf3nowTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4;
Te6edf3dataTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72= Te6edf3REQ_TYPE_KEEP_ALIVETb4b4b4;
Te6edf3memcpyTb4b4b4(Tff7b72&Te6edf3dataTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4, Tff7b72&Te6edf3contactTff7b72-Tff7b72>Te6edf3sync_sinceTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4;
T8b949e// calc expected ACK reply
Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3sha256Tb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4)Tff7b72&Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3expected_ackTb4b4b4, T79c0ff4Tb4b4b4, Te6edf3dataTb4b4b4, T79c0ff9Tb4b4b4, Te6edf3self_idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3pkt Tff7b72= Te6edf3createDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_REQTb4b4b4, Te6edf3contactTff7b72-Tff7b72>Te6edf3idTb4b4b4, Te6edf3contactTff7b72-Tff7b72>Te6edf3getSharedSecretTb4b4b4(Te6edf3self_idTb4b4b4)Tb4b4b4, Te6edf3dataTb4b4b4, T79c0ff9Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Tb4b4b4{
Te6edf3sendDirectTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3contactTff7b72-Tff7b72>Te6edf3out_pathTb4b4b4, Te6edf3contactTff7b72-Tff7b72>Te6edf3out_path_lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// schedule next KEEP_ALIVE
Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3next_ping Tff7b72= Te6edf3futureMillisTb4b4b4(Te6edf3connectionsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3keep_alive_millisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::resetPathToTb4b4b4(Te6edf3ContactInfoTff7b72& Te6edf3recipientTb4b4b4) Tb4b4b4{
Te6edf3recipientTb4b4b4.Te6edf3out_path_len Tff7b72= Te6edf3OUT_PATH_UNKNOWNTb4b4b4;
Tb4b4b4}
Tff7b72static Te6edf3ContactInfoTff7b72* Te6edf3tableTb4b4b4; T8b949e// pass via global :-(
Tff7b72static Tffa657int Td2a8ffcmp_adv_timestampTb4b4b4(Tff7b72const Tffa657void Tff7b72*Te6edf3aTb4b4b4, Tff7b72const Tffa657void Tff7b72*Te6edf3bTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3a_idx Tff7b72= Tff7b72*Tb4b4b4(Tb4b4b4(Tffa657int Tff7b72*Tb4b4b4)Te6edf3aTb4b4b4)Tb4b4b4;
Tffa657int Te6edf3b_idx Tff7b72= Tff7b72*Tb4b4b4(Tb4b4b4(Tffa657int Tff7b72*Tb4b4b4)Te6edf3bTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3tableTb4b4b4[Te6edf3b_idxTb4b4b4]Tb4b4b4.Te6edf3last_advert_timestamp Tff7b72> Te6edf3tableTb4b4b4[Te6edf3a_idxTb4b4b4]Tb4b4b4.Te6edf3last_advert_timestampTb4b4b4) Tff7b72return T79c0ff1Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3tableTb4b4b4[Te6edf3b_idxTb4b4b4]Tb4b4b4.Te6edf3last_advert_timestamp Tff7b72< Te6edf3tableTb4b4b4[Te6edf3a_idxTb4b4b4]Tb4b4b4.Te6edf3last_advert_timestampTb4b4b4) Tff7b72return T79c0ff-1Tb4b4b4;
Tff7b72return T79c0ff0Tb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::scanRecentContactsTb4b4b4(Tffa657int Te6edf3last_nTb4b4b4, Te6edf3ContactVisitorTff7b72* Te6edf3visitorTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3num_contactsTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{ T8b949e// sort the INDEXES into contacts[]
Te6edf3sort_arrayTb4b4b4[Te6edf3iTb4b4b4] Tff7b72= Te6edf3iTb4b4b4;
Tb4b4b4}
Te6edf3table Tff7b72= Te6edf3contactsTb4b4b4; T8b949e// pass via global *sigh* :-(
Te6edf3qsortTb4b4b4(Te6edf3sort_arrayTb4b4b4, Te6edf3num_contactsTb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3sort_arrayTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)Tb4b4b4, Te6edf3cmp_adv_timestampTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3last_n Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3last_n Tff7b72= Te6edf3num_contactsTb4b4b4; T8b949e// scan ALL
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3last_n Tff7b72> Te6edf3num_contactsTb4b4b4) Te6edf3last_n Tff7b72= Te6edf3num_contactsTb4b4b4;
Tb4b4b4}
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3last_nTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Te6edf3visitorTff7b72-Tff7b72>Te6edf3onContactVisitTb4b4b4(Te6edf3contactsTb4b4b4[Te6edf3sort_arrayTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3ContactInfoTff7b72* Td2a8ffBaseChatMesh::searchContactsByPrefixTb4b4b4(Tff7b72const Tffa657charTff7b72* Te6edf3name_prefixTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3len Tff7b72= Te6edf3strlenTb4b4b4(Te6edf3name_prefixTb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3num_contactsTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3c Tff7b72= Tff7b72&Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3cTff7b72-Tff7b72>Te6edf3nameTb4b4b4, Te6edf3name_prefixTb4b4b4, Te6edf3lenTb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tff7b72return Te6edf3cTb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657NULLTb4b4b4; T8b949e// not found
Tb4b4b4}
Te6edf3ContactInfoTff7b72* Td2a8ffBaseChatMesh::lookupContactByPubKeyTb4b4b4(Tff7b72const Tffa657uint8_tTff7b72* Te6edf3pub_keyTb4b4b4, Tffa657int Te6edf3prefix_lenTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3num_contactsTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3c Tff7b72= Tff7b72&Te6edf3contactsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3cTff7b72-Tff7b72>Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3pub_keyTb4b4b4, Te6edf3prefix_lenTb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tff7b72return Te6edf3cTb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657NULLTb4b4b4; T8b949e// not found
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::addContactTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3contactTb4b4b4) Tb4b4b4{
Te6edf3ContactInfoTff7b72* Te6edf3dest Tff7b72= Te6edf3allocateContactSlotTb4b4b4(Te6edf3contactTb4b4b4.Te6edf3type Tff7b72=Tff7b72= Te6edf3ADV_TYPE_NONETb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3destTb4b4b4) Tb4b4b4{
Tff7b72*Te6edf3dest Tff7b72= Te6edf3contactTb4b4b4;
Te6edf3destTff7b72-Tff7b72>Te6edf3shared_secret_valid Tff7b72= Tffa657falseTb4b4b4; T8b949e// mark shared_secret as needing calculation
Tff7b72return Tffa657trueTb4b4b4; T8b949e// success
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::removeContactTb4b4b4(Te6edf3ContactInfoTff7b72& Te6edf3contactTb4b4b4) Tb4b4b4{
Tffa657int Te6edf3idx Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3idx Tff7b72< Te6edf3num_contacts Tff7b72&Tff7b72& Tff7b72!Te6edf3contactsTb4b4b4[Te6edf3idxTb4b4b4]Tb4b4b4.Te6edf3idTb4b4b4.Te6edf3matchesTb4b4b4(Te6edf3contactTb4b4b4.Te6edf3idTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3idxTff7b72+Tff7b72+Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3idx Tff7b72>Tff7b72= Te6edf3num_contactsTb4b4b4) Tff7b72return Tffa657falseTb4b4b4; T8b949e// not found
T8b949e// remove from contacts array
Te6edf3num_contactsTff7b72-Tff7b72-Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3idx Tff7b72< Te6edf3num_contactsTb4b4b4) Tb4b4b4{
Te6edf3contactsTb4b4b4[Te6edf3idxTb4b4b4] Tff7b72= Te6edf3contactsTb4b4b4[Te6edf3idx Tff7b72+ T79c0ff1Tb4b4b4]Tb4b4b4;
Te6edf3idxTff7b72+Tff7b72+Tb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657trueTb4b4b4; T8b949e// Success
Tb4b4b4}
Tff7b72#Tff7b72ifdef MAX_GROUP_CHANNELS
Tff7b72#Tff7b72include T8b949e<base64.hpp>
Te6edf3ChannelDetailsTff7b72* Td2a8ffBaseChatMesh::addChannelTb4b4b4(Tff7b72const Tffa657charTff7b72* Te6edf3nameTb4b4b4, Tff7b72const Tffa657charTff7b72* Te6edf3psk_base64Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3num_channels Tff7b72< Te6edf3MAX_GROUP_CHANNELSTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3dest Tff7b72= Tff7b72&Te6edf3channelsTb4b4b4[Te6edf3num_channelsTb4b4b4]Tb4b4b4;
Te6edf3memsetTb4b4b4(Te6edf3destTff7b72-Tff7b72>Te6edf3channelTb4b4b4.Te6edf3secretTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3destTff7b72-Tff7b72>Te6edf3channelTb4b4b4.Te6edf3secretTb4b4b4)Tb4b4b4)Tb4b4b4;
Tffa657int Te6edf3len Tff7b72= Te6edf3decode_base64Tb4b4b4(Tb4b4b4(Tffa657unsigned Tffa657char Tff7b72*Tb4b4b4) Te6edf3psk_base64Tb4b4b4, Te6edf3strlenTb4b4b4(Te6edf3psk_base64Tb4b4b4)Tb4b4b4, Te6edf3destTff7b72-Tff7b72>Te6edf3channelTb4b4b4.Te6edf3secretTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3len Tff7b72=Tff7b72= T79c0ff32 Tff7b72|Tff7b72| Te6edf3len Tff7b72=Tff7b72= T79c0ff16Tb4b4b4) Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3sha256Tb4b4b4(Te6edf3destTff7b72-Tff7b72>Te6edf3channelTb4b4b4.Te6edf3hashTb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3destTff7b72-Tff7b72>Te6edf3channelTb4b4b4.Te6edf3hashTb4b4b4)Tb4b4b4, Te6edf3destTff7b72-Tff7b72>Te6edf3channelTb4b4b4.Te6edf3secretTb4b4b4, Te6edf3lenTb4b4b4)Tb4b4b4;
Te6edf3StrHelperTff7b72:Tff7b72:Te6edf3strncpyTb4b4b4(Te6edf3destTff7b72-Tff7b72>Te6edf3nameTb4b4b4, Te6edf3nameTb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3destTff7b72-Tff7b72>Te6edf3nameTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3num_channelsTff7b72+Tff7b72+Tb4b4b4;
Tff7b72return Te6edf3destTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72return Tffa657NULLTb4b4b4;
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::getChannelTb4b4b4(Tffa657int Te6edf3idxTb4b4b4, Te6edf3ChannelDetailsTff7b72& Te6edf3destTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3idx Tff7b72>Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3idx Tff7b72< Te6edf3MAX_GROUP_CHANNELSTb4b4b4) Tb4b4b4{
Te6edf3dest Tff7b72= Te6edf3channelsTb4b4b4[Te6edf3idxTb4b4b4]Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::setChannelTb4b4b4(Tffa657int Te6edf3idxTb4b4b4, Tff7b72const Te6edf3ChannelDetailsTff7b72& Te6edf3srcTb4b4b4) Tb4b4b4{
Tff7b72static Tffa657uint8_t Te6edf3zeroesTb4b4b4[Tb4b4b4] Tff7b72= Tb4b4b4{ T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0 Tb4b4b4}Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3idx Tff7b72>Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3idx Tff7b72< Te6edf3MAX_GROUP_CHANNELSTb4b4b4) Tb4b4b4{
Te6edf3channelsTb4b4b4[Te6edf3idxTb4b4b4] Tff7b72= Te6edf3srcTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Tff7b72&Te6edf3srcTb4b4b4.Te6edf3channelTb4b4b4.Te6edf3secretTb4b4b4[T79c0ff16Tb4b4b4]Tb4b4b4, Te6edf3zeroesTb4b4b4, T79c0ff16Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3sha256Tb4b4b4(Te6edf3channelsTb4b4b4[Te6edf3idxTb4b4b4]Tb4b4b4.Te6edf3channelTb4b4b4.Te6edf3hashTb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3channelsTb4b4b4[Te6edf3idxTb4b4b4]Tb4b4b4.Te6edf3channelTb4b4b4.Te6edf3hashTb4b4b4)Tb4b4b4, Te6edf3srcTb4b4b4.Te6edf3channelTb4b4b4.Te6edf3secretTb4b4b4, T79c0ff16Tb4b4b4)Tb4b4b4; T8b949e// 128-bit key
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3sha256Tb4b4b4(Te6edf3channelsTb4b4b4[Te6edf3idxTb4b4b4]Tb4b4b4.Te6edf3channelTb4b4b4.Te6edf3hashTb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3channelsTb4b4b4[Te6edf3idxTb4b4b4]Tb4b4b4.Te6edf3channelTb4b4b4.Te6edf3hashTb4b4b4)Tb4b4b4, Te6edf3srcTb4b4b4.Te6edf3channelTb4b4b4.Te6edf3secretTb4b4b4, T79c0ff32Tb4b4b4)Tb4b4b4; T8b949e// 256-bit key
Tb4b4b4}
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tffa657int Td2a8ffBaseChatMesh::findChannelIdxTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3GroupChannelTff7b72& Te6edf3chTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tffa657int Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3MAX_GROUP_CHANNELSTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3chTb4b4b4.Te6edf3secretTb4b4b4, Te6edf3channelsTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4.Te6edf3channelTb4b4b4.Te6edf3secretTb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3chTb4b4b4.Te6edf3secretTb4b4b4)Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tff7b72return Te6edf3iTb4b4b4;
Tb4b4b4}
Tff7b72return T79c0ff-1Tb4b4b4; T8b949e// not found
Tb4b4b4}
Tff7b72#Tff7b72else
Te6edf3ChannelDetailsTff7b72* Td2a8ffBaseChatMesh::addChannelTb4b4b4(Tff7b72const Tffa657charTff7b72* Te6edf3nameTb4b4b4, Tff7b72const Tffa657charTff7b72* Te6edf3psk_base64Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657NULLTb4b4b4; T8b949e// not supported
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::getChannelTb4b4b4(Tffa657int Te6edf3idxTb4b4b4, Te6edf3ChannelDetailsTff7b72& Te6edf3destTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tffa657bool Td2a8ffBaseChatMesh::setChannelTb4b4b4(Tffa657int Te6edf3idxTb4b4b4, Tff7b72const Te6edf3ChannelDetailsTff7b72& Te6edf3srcTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657falseTb4b4b4;
Tb4b4b4}
Tffa657int Td2a8ffBaseChatMesh::findChannelIdxTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3GroupChannelTff7b72& Te6edf3chTb4b4b4) Tb4b4b4{
Tff7b72return T79c0ff-1Tb4b4b4; T8b949e// not found
Tb4b4b4}
Tff7b72#Tff7b72endif
Tffa657bool Td2a8ffBaseChatMesh::getContactByIdxTb4b4b4(Tffa657uint32_t Te6edf3idxTb4b4b4, Te6edf3ContactInfoTff7b72& Te6edf3contactTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3idx Tff7b72>Tff7b72= Te6edf3num_contactsTb4b4b4) Tff7b72return Tffa657falseTb4b4b4;
Te6edf3contact Tff7b72= Te6edf3contactsTb4b4b4[Te6edf3idxTb4b4b4]Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Te6edf3ContactsIterator Td2a8ffBaseChatMesh::startContactsIteratorTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3ContactsIteratorTb4b4b4(Te6edf3MAX_ANON_CONTACTSTb4b4b4)Tb4b4b4; T8b949e// start at offset, skip the anon entries
Tb4b4b4}
Tffa657bool Td2a8ffContactsIterator::hasNextTb4b4b4(Tff7b72const Te6edf3BaseChatMeshTff7b72* Te6edf3meshTb4b4b4, Te6edf3ContactInfoTff7b72& Te6edf3destTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3next_idx Tff7b72>Tff7b72= Te6edf3meshTff7b72-Tff7b72>Te6edf3getTotalContactSlotsTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return Tffa657falseTb4b4b4;
Te6edf3dest Tff7b72= Te6edf3meshTff7b72-Tff7b72>Te6edf3contactsTb4b4b4[Te6edf3next_idxTff7b72+Tff7b72+Tb4b4b4]Tb4b4b4;
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffBaseChatMesh::loopTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3MeshTff7b72:Tff7b72:Te6edf3loopTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3txt_send_timeout Tff7b72&Tff7b72& Te6edf3millisHasNowPassedTb4b4b4(Te6edf3txt_send_timeoutTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// failed to get an ACK
Te6edf3onSendTimeoutTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3txt_send_timeout Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3_pendingLoopbackTb4b4b4) Tb4b4b4{
Te6edf3onRecvPacketTb4b4b4(Te6edf3_pendingLoopbackTb4b4b4)Tb4b4b4; T8b949e// loop-back, as if received over radio
Te6edf3releasePacketTb4b4b4(Te6edf3_pendingLoopbackTb4b4b4)Tb4b4b4; T8b949e// undo the obtainNewPacket()
Te6edf3_pendingLoopback Tff7b72= Tffa657NULLTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Served by rngit 1.5.0 - Generated in 0.36s